package quotation.config;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.util.StringUtils;
import quotation.utils.CommonFieldUtil;
import quotation.utils.LoginInfoUtil;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;




public class SqlInnerInterceptor implements InnerInterceptor {
    @Override
    public void beforeUpdate(Executor executor, MappedStatement ms, Object parameter) {
        if (parameter != null) {
            TableInfo tableInfo = null;
            Object entity = parameter;
            String sqlSet = "";
            if (parameter instanceof Map) {
                Map<Object, Object> map = (Map<Object, Object>) parameter;
                if (map.containsKey(Constants.ENTITY)) {
                    Object et = map.get(Constants.ENTITY);
                    if (et != null) {
                        entity = et;
                        tableInfo = TableInfoHelper.getTableInfo(entity.getClass());
                    }else{
                        Class<?> type = ms.getParameterMap().getType();
                        try {
                            entity= type.newInstance();
                            sqlSet = ((LambdaUpdateWrapper) map.get("ew")).getSqlSet();
                            map.put(Constants.ENTITY,entity);
                            tableInfo = TableInfoHelper.getTableInfo(type);
                        } catch (InstantiationException | IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            } else {
                tableInfo = TableInfoHelper.getTableInfo(parameter.getClass());
            }
            if (tableInfo != null) {
                //到这里就应该转换到实体参数对象了,因为填充和ID处理都是争对实体对象处理的,不用传递原参数对象下去.
                MetaObject metaObject = ms.getConfiguration().newMetaObject(entity);
                if (SqlCommandType.INSERT == ms.getSqlCommandType()) {
                    insertFill(metaObject);
                } else {
                    updateFill(metaObject,sqlSet);
                }
            }
        }
    }

    private void insertFill(MetaObject metaObject) {
        LoginInfoUtil user = LoginInfoUtil.getInstance();
        TableInfo tableInfo = TableInfoHelper.getTableInfo(metaObject.getOriginalObject().getClass());
        List<TableFieldInfo> fieldList = tableInfo.getFieldList();
        for (TableFieldInfo fieldInfo : fieldList) {
            if(!fieldInfo.isWithInsertFill()){
                String property = fieldInfo.getProperty();
                if(CommonFieldUtil.CommonField.PH_INSERT_DT.equals(property)&&metaObject.getValue(CommonFieldUtil.CommonField.PH_INSERT_DT)==null){
                    metaObject.setValue(CommonFieldUtil.CommonField.PH_INSERT_DT, LocalDateTime.now());
                }
                if(CommonFieldUtil.CommonField.PH_USER_ID.equals(property)&&metaObject.getValue(CommonFieldUtil.CommonField.PH_USER_ID)==null){
                    metaObject.setValue(CommonFieldUtil.CommonField.PH_USER_ID, user.getUserId());
                }
                if(CommonFieldUtil.CommonField.PH_CREATOR.equals(property)&&metaObject.getValue(CommonFieldUtil.CommonField.PH_CREATOR)==null){
                    metaObject.setValue(CommonFieldUtil.CommonField.PH_CREATOR, StringUtils.isEmpty(user.getName())?"system":user.getName());
                }
            }
        }
    }


    private void updateFill(MetaObject metaObject,String sqlSet) {
        sqlSet=sqlSet.toLowerCase();
        LoginInfoUtil user = LoginInfoUtil.getInstance();
        TableInfo tableInfo = TableInfoHelper.getTableInfo(metaObject.getOriginalObject().getClass());
        List<TableFieldInfo> fieldList = tableInfo.getFieldList();
        for (TableFieldInfo fieldInfo : fieldList) {
            if(!fieldInfo.isWithUpdateFill()){
                String property = fieldInfo.getProperty();
                if(!sqlSet.contains(CommonFieldUtil.CommonCol.PH_UPDATE_DT)&& CommonFieldUtil.CommonField.PH_UPDATE_DT.equals(property)){
                    metaObject.setValue(CommonFieldUtil.CommonField.PH_UPDATE_DT, LocalDateTime.now());
                }
                if(!sqlSet.contains(CommonFieldUtil.CommonCol.PH_EDITOR_ID)&& CommonFieldUtil.CommonField.PH_EDITOR_ID.equals(property)){
                    metaObject.setValue(CommonFieldUtil.CommonField.PH_EDITOR_ID, user.getUserId());
                }
                if(!sqlSet.contains(CommonFieldUtil.CommonCol.PH_EDITOR_NAME)&& CommonFieldUtil.CommonField.PH_EDITOR_NAME.equals(property)){
                    metaObject.setValue(CommonFieldUtil.CommonField.PH_EDITOR_NAME, StringUtils.isEmpty(user.getName())?"system":user.getName());
                }
            }

        }
    }
}
